package com.xmxsuperstar.app.client.twitter;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import net.love5z.common.json.JSONArray;
import net.love5z.common.json.JSONException;
import net.love5z.common.json.JSONObject;
import net.love5z.common.utils.StringUtils;
import android.util.Log;

import com.xmxsuperstar.app.client.ClientConstants;
import com.xmxsuperstar.app.client.twitter.model.TwitterStatus;
import com.xmxsuperstar.app.client.twitter.model.TwitterUser;

public abstract class TwitterTimeLineClient extends TwitterClient {

    private Map<String, String> extraParams = new HashMap<String, String>();

    public List<TwitterStatus> getTimeLine(int count) {
        String param1 = StringUtils.contact("=", "count", String.valueOf(count));
        String param2 = StringUtils.contact("=", "include_entities", "1");
        String extraParam = this.buildExtraParam();
        String params = StringUtils.contact("&", param1, param2, extraParam);
        String requestUrl = StringUtils.contact("?", this.getBaseUrlStr(), params);

        String response = this.get(requestUrl);

        return parase(response);
    }

    public List<TwitterStatus> getTimeLineBySinceId(long sinceId, int count) {
        String param1 = StringUtils.contact("=", "since_id", String.valueOf(sinceId));
        String param2 = StringUtils.contact("=", "count", String.valueOf(count));
        String param3 = StringUtils.contact("=", "include_entities", "1");
        String extraParam = this.buildExtraParam();
        String params = StringUtils.contact("&", param1, param2, param3, extraParam);
        String requestUrl = StringUtils.contact("?", this.getBaseUrlStr(), params);

        String response = this.get(requestUrl);

        return parase(response);
    }

    public List<TwitterStatus> getTimeLineByMaxId(long maxId, int count) {
        String param1 = StringUtils.contact("=", "max_id", String.valueOf(maxId));
        String param2 = StringUtils.contact("=", "count", String.valueOf(count));
        String param3 = StringUtils.contact("=", "include_entities", "1");
        String extraParam = this.buildExtraParam();
        String params = StringUtils.contact("&", param1, param2, param3, extraParam);
        String requestUrl = StringUtils.contact("?", this.getBaseUrlStr(), params);

        String response = this.get(requestUrl);

        return parase(response);
    }

    protected abstract String getBaseUrlStr();

    protected List<TwitterStatus> parase(String content) {
        List<TwitterStatus> list = new ArrayList<TwitterStatus>();

        try {
            JSONArray stArray = new JSONArray(content);
            for (int i = 0; i < stArray.length(); i++) {
                JSONObject st = stArray.getJSONObject(i);

                TwitterStatus status = new TwitterStatus();
                status.setId(st.getLong("id"));
                String text = st.getString("text");

                JSONArray urlArray = st.getJSONObject("entities").getJSONArray("urls");
                for (int j = 0; j < urlArray.length(); j++) {
                    String url = urlArray.getJSONObject(j).getString("url");
                    String expandUrl = urlArray.getJSONObject(j).getString("expanded_url");
                    text = text.replace(url, expandUrl);

                    if (expandUrl.contains("instagr.am")) {
                        //https://instagr.am/p/JlaapaiKAO/media/?size=l
                        status.setPicUrl(expandUrl + "media/?size=l");
                    }
                }

                status.setText(text);

                SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZZZ yyyy",
                    Locale.ENGLISH);
                sdf.setLenient(false);
                status.setCreatedAt(sdf.parse(st.getString("created_at")));

                TwitterUser user = new TwitterUser();
                user.setId(st.getJSONObject("user").getLong("id"));
                user.setName(st.getJSONObject("user").getString("name"));
                user.setProfileImageUrl(new URL(st.getJSONObject("user").getString(
                    "profile_image_url")));
                user.setScreenName(st.getJSONObject("user").getString("screen_name"));

                status.setUser(user);

                Object inReplyToUserIdStr = st.get("in_reply_to_user_id_str");
                if (inReplyToUserIdStr instanceof String) {
                    status.setInReplyToUserIdStr(inReplyToUserIdStr.toString());
                }

                list.add(status);
            }
        } catch (JSONException e) {
            Log.e(ClientConstants.LogTag, e.getMessage());
        } catch (ParseException e) {
            Log.e(ClientConstants.LogTag, e.getMessage());
        } catch (MalformedURLException e) {
            Log.e(ClientConstants.LogTag, e.getMessage());
        }

        return list;
    }

    private String buildExtraParam() {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> queryParam : extraParams.entrySet()) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(StringUtils.contact("=", queryParam.getKey(), queryParam.getValue()));
        }

        return sb.toString();
    }

    public void addExtraParam(String name, String value) {
        extraParams.put(name, value);
    }
}
